﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Flurl.Http;
using Pay.Core;
using Pay.DTO;
using Pay.DTO.xsft3;
using Pay.IService;
using Pay.TO;

namespace Pay.Service {
    public class Xsft3Service : ServiceBase2, IPayService, IDisposable {
        private IUnitOfWork _iUnitOfWork;
        private ISettingService _iSettingService;
        private IMerchantService _iMerchantService;
        private IChargeService _iChargeService;
        private IProfitDayService _iProfitDayService;
        private IBillService _iBillService;
        private IPayHtmlService _iPayHtmlService;
        private IRegionService _iRegionService;
        private IPayNotifyService _iPayNotifyService;
        private Xsft3Sign _xsft3Sign;
        private const string order_pay_url = "/cctp/{0}/placeorder.json";
        private const string order_query_url = "/cctp/{0}/queryOrder.json";
        private const string merchant_reg_url = "/cctp/{0}/merchant.json";
        private const string order_confirm_url = "/cctp/{0}/confirmPay.json";

        public Xsft3Service(IUnitOfWork iUnitOfWork, ISettingService iSettingService, IPayNotifyService iPayNotifyService,
                                        IMerchantService iMerchantService, IChargeService iChargeService,
                                        IProfitDayService iProfitDayService, IBillService iBillService,
                                        IPayHtmlService iPayHtmlService, IRegionService iRegionService) : base(iUnitOfWork) {
            _iUnitOfWork = iUnitOfWork;
            _iSettingService = iSettingService;
            _iMerchantService = iMerchantService;
            _iChargeService = iChargeService;
            _iProfitDayService = iProfitDayService;
            _iBillService = iBillService;
            _iPayHtmlService = iPayHtmlService;
            _iRegionService = iRegionService;
            _iPayNotifyService = iPayNotifyService;
            _xsft3Sign = new Xsft3Sign();
        }

        #region 扫码的
        /// <summary>
        /// 生成二维码扫码请求通道封装
        /// </summary>
        /// <returns>The pay gateway.</returns>
        /// <param name="model">Model.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public Task<native_result> NativePay(native_model model) {
            throw new NotImplementedException();
        }
        #endregion

        #region 支付异步通知
        /// <summary>
        /// 回调支付通知，商户返回OK，不再回调了，流程是先调用ChargeService的NotifyOrder，
        /// 返回值判断是调用哪个通道，再调用本方法，最后调用ChargeService的Update
        /// </summary>
        /// <returns>The notify.</returns>
        /// <param name="order_no">Order.</param>
        public async Task<string> Notify(string merchant_no, string order_no) {
            string result = string.Empty;
            charge_dto order = _iChargeService.Get(merchant_no, order_no);
            try {
                var data = new pay_notity {
                    tran_amount = ((int)(order.order_amount * 100)).ToString(), order_no = order.order_no, transaction_no = order.pay_info.transaction_no,
                    pay_time = order.pay_info.pay_time.HasValue ? order.pay_info.pay_time.Value : order.order_time,
                    status = (order.status == ChargeStatus.Finish ? 1 : 2)
                };
                //失败的要再查询通道判断是否真失败,处理掉单
                //if (order.status != ChargeStatus.Finish) {
                //	var pay_model = new hx_head_base();
                //	pay_model.client_trans_id = order.order_no;
                //	pay_model.trans_timestamp = DateTime.Now.ToUnix();
                //	pay_model.data = data.ToJson();
                //	pay_model.sign = _xsft3Sign.Sign(pay_model);
                //	var resultApi = await _xsft3Sign.PayGateway<hx_query_result>(pay_model);
                //	if (resultApi != null) {
                //		if (resultApi.resp_code == "000000" && resultApi.data.resp_code == "PAY_SUCCESS" /*&& resultApi.data.withdrawals_status == "WITHDRAWALS_SUCCESS"*/) {
                //			data.status = 1;
                //			var pay_time = DateTime.Now;
                //			_iChargeService.FailOrUnConfirmToSuceess(merchant_no, order.order_no, pay_time);
                //		}
                //	}
                //}
                data.result_msg = (data.status == 1 ? "支付成功" : order.fail);
                if (string.IsNullOrEmpty(order.notify)) return "OK";
                var notify_result = await order.notify.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveJson<ResultMessage<string>>();
                result = notify_result.data;
                var log = IocHelper.Get<ILogHelper>("info");
                log.Info(order.order_no + ":" + notify_result.ToJson());
            } catch (Exception ex) {
                var log = IocHelper.Get<ILogHelper>("info");
                log.Error("订单通道查询异常:" + order.order_no);
                string message = string.Format("消息类型：{0}\r\n消息内容：{1}\r\n引发异常的方法：{2}\r\n引发异常源：{3}"
                                , ex.GetType().Name, ex.Message, ex.TargetSite, ex.Source + ex.StackTrace);
                log.Error(message);
            }
            return result;
        }

        /// <summary>
        /// 代付通知－不可用
        /// </summary>
        /// <returns>The transfer.</returns>
        /// <param name="order_no">Order.</param>
        public Task<string> NotifyTransfer(string merchant_no, string order_no) {
            throw new NotImplementedException();
        }
        #endregion

        #region 实名、T0额度-不可用
        /// <summary>
        /// 查询代付T0额度
        /// </summary>
        /// <returns>The quota.</returns>
        /// <param name="merchant_no"></param>
        /// <param name="busiType">0：对公 1：对私</param>
        public Task<quota_result> Quota(string merchant_no, string busiType) {
            throw new NotImplementedException();
        }
        #endregion

        #region 快捷同卡同出
        /// <summary>
        /// 快捷支付
        /// </summary>
        /// <returns>The receive.</returns>
        /// <param name="model">Model.</param>
        public async Task<quick_pay_result> QuickPay(quick_pay_model model) {
            var log = IocHelper.Get<ILogHelper>("info");
            var binder = _iMerchantService.Get(model.bind_no);
            string mobile = binder.setting.auth_info.mobile;
            var setting = _iSettingService.Get();
            string merCode = _iMerchantService.IsRegisterChannel(mobile);
            if (string.IsNullOrEmpty(merCode)) {
                var res = await MerchantRegister(binder.id, "A", model.pay_channel);
                if (res.result_code != 1000)
                    return ApiResultToJson.Json<quick_pay_result>(res.result_msg, 2001);
                else
                    merCode = res.merchant_no;
            }
            string pay_code = model.pay_code;
            model.settle_type = "T0";
            var binder_payments = _iMerchantService.GetPayments(binder.id);
            var payment = binder_payments.FirstOrDefault(c => c.payment.channel == model.pay_channel);
            var settle = payment.settles.First(c => c.settle_type == model.settle_type && c.code == pay_code);
            if (model.settle_fee / 100M != settle.settle)
                return ApiResultToJson.Json<quick_pay_result>("结算费与商户进件的结算费不同");
            if (model.fee != settle.fee)
                return ApiResultToJson.Json<quick_pay_result>("费率与商户进件的费率不同");
            if (model.pay_fee_amount != (int)Math.Ceiling(decimal.Parse(model.tran_amount) * model.fee))
                return ApiResultToJson.Json<quick_pay_result>("实扣费率金额不正确");
            string merchant_url = SetUrlByChannel(model.pay_channel, merchant_reg_url);
            var m6 = new merchant_edit_m6 { merCode = merCode, Service = _xsft3Sign.Services[model.pay_channel] };
            var m6Api = await _xsft3Sign.PayGateway<merchant_resp>(m6, merchant_url);
            if (m6Api != null && Convert.ToDecimal(m6Api.Rate) != model.fee) {
                log.Info(m6Api.ToJson());
                var m4 = new merchant_edit_m4();
                m4.Service = _xsft3Sign.Services[model.pay_channel];
                m4.merCode = merCode;
                var dto = new merchant_register_model();
                dto.fee = model.fee;
                dto.settle = model.settle_fee.ToString();
                SetPayType(m4, dto);
                var m4Api = await _xsft3Sign.PayGateway<merchant_resp>(m4, merchant_url);
                log.Info("修改费率成功");
            }

            //把商户请求转为通道请求消息
            var id = Guid.NewGuid().ToString("N");
            var notify = setting.site.api_url + "/pay/xsft3_back_notify/" + id;
            var frontNotify = string.Format("{0}/pay/html_front/{1}", setting.site.api_url, id);
            string withdrawUrl = string.Format("{0}/pay/klt_success", setting.site.api_url);
            var dt = DateTime.Now;
            decimal amt = decimal.Parse(model.tran_amount) / 100M;
            var pay_model = new xsft3_kj_req {
                Service = _xsft3Sign.Services[model.pay_channel],
                merCode = merCode,
                totalFee = model.tran_amount,
                accMobile = model.mobile,
                accType = "DEBIT",
                accName = model.account_name,
                accNo = model.account_no,
                backUrl = notify,
                ProductName = "商品名称",
                withdrawUrl = withdrawUrl,
                merOrderId = model.order_no,
                frontUrl = frontNotify,
                bankCode = SetMerchantBankCode(model.bank_code)
            };
            if (string.IsNullOrEmpty(model.cvv2)) {
                model.cvv2 = "123";
            }
            if (!string.IsNullOrEmpty(model.cvv2)) {
                pay_model.cvn2 = SecureHelper.EncodeBase64(model.cvv2);
            }
            if (!string.IsNullOrEmpty(model.vaild)) {
                string head = model.vaild.Substring(0, 2);
                string last = model.vaild.Substring(2);
                pay_model.expDate = SecureHelper.EncodeBase64(last + head);
            }
            var charge = _iChargeService.AddByQuickPay(model);
            string url = SetUrlByChannel(model.pay_channel, order_pay_url);
            var resultApi = await _xsft3Sign.PayGateway<xsft3_kj_resp>(pay_model, url);
            //调用通道执行并处理返回，请通道响应消息封装为平台响应商户消息
            if (resultApi != null) {
                if (resultApi.resCode.Equals("0000") || resultApi.resCode.Equals("080006")) {
                    string requestUrl = string.Empty;
                    if (resultApi.transType.Equals("1030")) {
                        requestUrl = string.Format("{0}/pay/html_front/{1}", setting.site.api_url, id);
                    } else if (resultApi.transType.Equals("1050")) {
                        requestUrl = resultApi.openUrl;
                    }
                    var ok = _iPayHtmlService.Save(new pay_html_dto {
                        id = id, merchant_no = model.merchant_no, order_no = model.order_no,
                        charge = charge.ToJson(), html = resultApi.openHtml
                    });
                    return ApiResultToJson.Json("鉴权成功，待确认支付", new quick_pay_result {
                        order_no = model.order_no, protocol_no = "", request_url = requestUrl,
                        pay_time = DateTime.Now, transaction_no = "", status = 3
                    });
                } else
                    return ApiResultToJson.Json<quick_pay_result>(resultApi.resMsg);
            }
            return ApiResultToJson.Json<quick_pay_result>("异常支付");
        }
        /// <summary>
        /// 快捷支付查询
        /// </summary>
        /// <returns>The pay query.</returns>
        /// <param name="model">Model.</param>
        public async Task<pay_notity> QuickPayQuery(refund_model_query model) {
            charge_dto order = _iChargeService.Get(model.merchant_no, model.order_no);
            var data = new pay_notity { result_msg = "支付失败", status = 2, order_no = model.order_no, pay_time = DateTime.Now };
            if (order == null) {
                var obj = _iPayHtmlService.Get(model.merchant_no, model.order_no);
                if (obj != null) {
                    order = obj.charge.ToObject<charge_dto>();
                    long bindId = (order.bind_id.HasValue ? order.bind_id.Value : order.merchant_id);
                    var merchant = _iMerchantService.Get(bindId);
                    string merchant_no = _iMerchantService.IsRegisterChannel(merchant.setting.auth_info.mobile);
                    var query_model = new xsft3_kjquery_req { merOrderId = model.order_no, merCode = merchant_no, ordtype = model.ordtype, Service = _xsft3Sign.Services[model.pay_channel] };
                    string url = SetUrlByChannel(model.pay_channel, order_query_url);
                    var resultApi = await _xsft3Sign.PayGateway<xsft3_resp_base>(query_model, url);
                    if (resultApi != null) {
                        var charge = obj.charge.ToObject<charge_dto>();
                        if (resultApi.resCode == "0000") {
                            data.status = 1;
                            data.pay_time = obj.create_time;
                            data.result_msg = "支付成功";
                            data.tran_amount = ((int)(charge.amount * 100)).ToString();
                            var result = _iChargeService.PaySuceess(obj, data.order_no, data.pay_time);
                            if (result > 0) {
                                var notifyResult = await Notify(charge.merchant_no, model.order_no);
                                _iPayHtmlService.Remove(obj.id);
                            }
                        } else {
                            data.result_msg = resultApi.resMsg;
                            data.tran_amount = ((int)(charge.amount * 100)).ToString();
                        }
                    }
                } else {
                    data.result_code = 1001; data.result_msg = "支付失败";
                }
            } else {
                data.status = order.status == ChargeStatus.Finish ? 1 : 2; data.pay_time = order.order_time; data.transaction_no = order.order_no;
                data.result_msg = order.status == ChargeStatus.Finish ? "支付成功" : "支付失败"; data.tran_amount = ((int)order.amount * 100).ToString();
                if (order.status != ChargeStatus.Finish) data.result_code = 1001;
            }
            return data;
        }
        #endregion

        #region 快捷支付－不可用
        /// <summary>
        /// 快捷支付鉴权成功后发短信
        /// </summary>
        /// <returns>The pay resms.</returns>
        /// <param name="model">model.</param>
        public async Task<ApiResultMessage> QuickPaySendsms(quick_sendsms_model model) {
            return await Task.FromResult(ApiResultToJson.Success("短信发送成功"));
        }

        /// <summary>
        /// 确认短信验证码
        /// </summary>
        /// <returns>The pay.</returns>
        /// <param name="model">model.</param>
        public async Task<quick_pay_result> QuickPay(quick_sms_model model) {
            var payHtml = _iPayHtmlService.Get(model.merchant_no, model.order_no);
            var charge = payHtml.charge.ToObject<charge_dto>();
            var merchant = _iMerchantService.Get(model.bind_no);
            string merchant_no = _iMerchantService.IsRegisterChannel(merchant.setting.auth_info.mobile);
            var sms_req = new xsft3_confirm_req {
                Service = _xsft3Sign.Services[model.pay_channel],
                merOrderId = model.order_no,
                merCode = merchant_no,
                smsCode = model.sms_code
            };
            string url = SetUrlByChannel(model.pay_channel, order_confirm_url);
            var resultApi = await _xsft3Sign.PayGateway<xsft3_resp_base>(sms_req, url);
            if (resultApi != null) {
                if (resultApi.resCode.Equals("0000")) {
                    var result = _iChargeService.PaySuceess(payHtml, model.order_no, DateTime.Now);
                    if (result > 0) {
                        var notifyResult = await Notify(charge.merchant_no, charge.order_no);
                        if (notifyResult != "OK") {
                            //创建通知消息对象
                            _iPayNotifyService.Save(new pay_notify_dto {
                                merchant_no = charge.merchant_no,
                                order_no = charge.order_no,
                                pay_channel = charge.pay_info.pay_channel,
                                type = 1,
                                status = 2,
                                create_time = DateTime.Now
                            });
                        }
                        _iPayHtmlService.Remove(payHtml.id);
                    }
                }
                return ApiResultToJson.Json<quick_pay_result>(resultApi.resMsg);
            }
            return ApiResultToJson.Json<quick_pay_result>("异常支付");
        }

        /// <summary>
        /// 快捷支付退款
        /// </summary>
        /// <returns>The pay refund.</returns>
        /// <param name="model">Model.</param>
        public Task<refund_result> QuickPayRefund(refund_model model) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 快捷支付退款查询,并将退款中的单处理为完成
        /// </summary>
        /// <returns>The pay refund.</returns>
        /// <param name="model">Model.</param>
        public Task<refund_result> QuickPayRefundQuery(refund_model_query model) {
            throw new NotImplementedException();
        }
        #endregion

        #region 网关支付-不可用
        /// <summary>
        /// 网关支付银行
        /// </summary>
        /// <returns>The pay bank.</returns>
        public List<type_setting> GatewayPayBank() {
            var banks = new List<type_setting>();
            banks.Add(new type_setting { value = "BOC", text = "中国银行" });
            banks.Add(new type_setting { value = "ABC", text = "中国农业银行" });
            banks.Add(new type_setting { value = "ICBC", text = "中国工商银行" });
            banks.Add(new type_setting { value = "CCB", text = "中国建设银行" });
            banks.Add(new type_setting { value = "COMM", text = "交通银行" });
            banks.Add(new type_setting { value = "PSBC", text = "中国邮政储蓄银行" });
            banks.Add(new type_setting { value = "CMB", text = "招商银行" });
            banks.Add(new type_setting { value = "CMBC", text = "中国民生银行" });
            banks.Add(new type_setting { value = "CITIC", text = "中信银行" });
            banks.Add(new type_setting { value = "CEB", text = "中国光大银行" });
            banks.Add(new type_setting { value = "HXB", text = "华夏银行" });
            banks.Add(new type_setting { value = "GDB", text = "广发银行" });
            banks.Add(new type_setting { value = "CIB", text = "兴业银行" });
            banks.Add(new type_setting { value = "SPDB", text = "上海浦东发展银行" });
            banks.Add(new type_setting { value = "SPAB", text = "平安银行" });
            banks.Add(new type_setting { value = "SHB", text = "上海银行" });
            banks.Add(new type_setting { value = "BJB", text = "北京银行" });
            banks.Add(new type_setting { value = "HZCB", text = "杭州银行" });
            return banks;
        }

        /// <summary>
        /// 发起网关支付
        /// </summary>
        /// <returns>The receive.</returns>
        /// <param name="model">Model.</param>
        public Task<gateway_pay_result> GatewayPay(gateway_pay_model model) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 网关支付查询
        /// </summary>
        /// <returns>The pay query.</returns>
        /// <param name="model">Model.</param>
        public Task<pay_notity> GatewayPayQuery(refund_model_query model) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 网关支付退款
        /// </summary>
        /// <returns>The pay refund.</returns>
        /// <param name="model">Model.</param>
        public Task<refund_result> GatewayPayRefund(refund_model model) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 网关支付退款查询,并将退款中的单处理为完成
        /// </summary>
        /// <returns>The pay refund.</returns>
        /// <param name="model">Model.</param>
        public Task<refund_result> GatewayRefundQuery(refund_model_query model) {
            throw new NotImplementedException();
        }
        #endregion

        #region 代付,T+0转账-不可用
        /// <summary>
        /// 单笔代付
        /// </summary>
        /// <returns>The transfer.</returns>
        /// <param name="model">Model.</param>
        public Task<transfer_result> Transfer(apply_transfer model) {
            throw new NotImplementedException();
        }
        public Task<transfer_result> ReTransfer(long id) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 代付批处理:生成代付文件，将批号写入提现表，生成代付文件记录，并上传FTP，FTP成功调用代付通知，FTP失败提示手动上传，并去文件记录管理手动代付通知。
        /// </summary>
        /// <returns>The transfer.</returns>
        /// <param name="model">Model.</param>
        public Task<batch_transfer_result> Transfer(batch_transfer model) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 提交代付批处理报盘通知（平台后台用）
        /// </summary>
        /// <returns>The transfer.</returns>
        /// <param name="batchId">Batch Id.</param>
        public Task<int> TransferNotify(long batchId, string batchFileName, long merchant_id) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 提交代付批处理查询，返回回盘文件地址后，进行提现记录更新（平台后台用）
        /// </summary>
        /// <returns>The transfer.</returns>
        /// <param name="batchId">Batch Id.</param>
        /// <param name="noticeTranId">报盘通知交易流水号</param>
        public Task<int> TransferBack(long batchId, string noticeTranId, long merchant_id) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 单笔代付查询
        /// </summary>
        /// <returns>The query.</returns>
        /// <param name="model">Model.</param>
        public Task<transfer_result> TransferQuery(transfer_query model) {
            throw new NotImplementedException();
        }
        #endregion

        #region 代收,T+1转账-不可用
        /// <summary>
        /// 代收签约
        /// </summary>
        /// <returns>The receive.</returns>
        /// <param name="model">Model.</param>
        public Task<ApiResultMessage> InsteadReceive(verify_model model) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 代收签约
        /// </summary>
        /// <returns>The receive.</returns>
        /// <param name="model">Model.</param>
        public Task<ApiResultMessage> InsteadReceive(verify_model_sms model) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 单笔代收
        /// </summary>
        /// <returns>The transfer.</returns>
        /// <param name="model">Model.</param>
        public Task<transfer_result> AgencyFund(apply_receive model) {
            throw new NotImplementedException();
        }
        #endregion

        #region 商户进件
        /// <summary>
        /// 返回的是第三方的商户号，opt：A增加，M修改
        /// </summary>
        /// <returns>The register.</returns>
        /// <param name="dto">Dto.</param>
        /// <param name="opt">A增加，M修改.</param>
        public async Task<merchant_register_result> MerchantRegister(merchant_register_model dto, string opt) {
            merchant_resp resultApi = null;
            var user = _iMerchantService.Get(dto.bind_no);
            var log = IocHelper.Get<ILogHelper>("info");
            string service = _xsft3Sign.Services[dto.pay_channel];
            log.Info("service：" + dto.pay_channel);
            if (opt == "A") {
                string merCode = _iMerchantService.IsRegisterChannel(dto.mobile);
                log.Info(merCode);
                if (string.IsNullOrEmpty(merCode)) {
                    var model = new merchant_req();
                    model.operFlag = opt;
                    model.merCode = dto.reg_merchant_no;
                    model.fullName = user.name + "个体观音山餐饮";
                    model.simpleName = user.name + "个体户";
                    model.Service = _xsft3Sign.Services[dto.pay_channel];
                    SetMerchantInfo(model, dto);
                    SetPayType(model, dto);
                    string url = SetUrlByChannel(dto.pay_channel, merchant_reg_url);
                    resultApi = await _xsft3Sign.PayGateway<merchant_resp>(model, url);
                    if (resultApi.resCode == "000202" && resultApi.resMsg == "商户已注册") {
                        dto.reg_merchant_no = resultApi.data;
                        resultApi = await UpdateChannel(dto);
                        if (resultApi.resCode == "0000") {
                            _iMerchantService.MerchantChannelRegister(dto);
                        }
                    }
                } else {
                    dto.reg_merchant_no = merCode;
                    resultApi = await UpdateChannel(dto);
                    if (resultApi.resCode == "0000") {
                        _iMerchantService.MerchantChannelRegister(dto);
                    }
                }
            } else {
                resultApi = await UpdateChannel(dto);
            }
            if (resultApi != null) {
                if (resultApi.resCode == "0000") {
                    dto.reg_merchant_no = resultApi.data;
                    return ApiResultToJson.Json(new merchant_register_result { merchant_no = dto.reg_merchant_no });
                } else {
                    return ApiResultToJson.Json<merchant_register_result>(resultApi.resMsg);
                }
            }
            return ApiResultToJson.Json<merchant_register_result>("信息登记异常");
        }

        private async Task<merchant_resp> UpdateChannel(merchant_register_model dto) {
            var log = IocHelper.Get<ILogHelper>("info");
            var user = _iMerchantService.Get(dto.bind_no);
            merchant_resp resultApi = null;
            string service = _xsft3Sign.Services[dto.pay_channel];
            string url = SetUrlByChannel(dto.pay_channel, merchant_reg_url);
            var m4 = new merchant_edit_m4();
            m4.Service = service;
            m4.merCode = dto.reg_merchant_no;
            SetPayType(m4, dto);
            resultApi = await _xsft3Sign.PayGateway<merchant_resp>(m4, url);
            log.Info("修改费率成功");

            //修改结算卡信息
            var m2 = new merchant_edit_m2();
            m2.Service = service;
            m2.merCode = dto.reg_merchant_no;
            m2.fullName = user.name + "个体观音山餐饮";
            m2.simpleName = user.name + "个体户";
            SetMerchantInfo(m2, dto);
            resultApi = await _xsft3Sign.PayGateway<merchant_resp>(m2, url);
            log.Info("修改结算卡成功");
            return resultApi;
        }

        /// <summary>
        /// 新增商户进件
        /// </summary>
        /// <returns>The register.</returns>
        /// <param name="bind_id">Bind identifier.</param>
        /// <param name="settle_type">Settle type.</param>
        /// <param name="channel">Channel.</param>
        public async Task<merchant_register_result> MerchantRegister(long bind_id, string settle_type, PayChannel channel) {
            var binder = _iMerchantService.Get(bind_id);
            var oemer = _iMerchantService.Get(binder.oem_id.Value);
            var model = new merchant_req();
            model.operFlag = "A";
            model.Service = _xsft3Sign.Services[channel];
            model.fullName = binder.name + "个体观音山餐饮";
            model.simpleName = binder.name + "个体户";
            SetMerchantInfo(model, binder);
            SetPayType(model, binder, channel);
            string url = SetUrlByChannel(channel, merchant_reg_url);
            var resultApi = await _xsft3Sign.PayGateway<merchant_resp>(model, url);
            if (resultApi != null) {
                if (resultApi.resCode == "0000") {
                    var dto = binder.setting.auth_info.ToDtoObject<merchant_register_model>();
                    dto.pay_channel = channel;
                    dto.reg_merchant_no = resultApi.data;
                    dto.bind_no = binder.merchant_no;
                    dto.merchant_no = oemer.merchant_no;
                    _iMerchantService.MerchantChannelRegister(dto);
                    return ApiResultToJson.Json(new merchant_register_result { merchant_no = dto.reg_merchant_no });
                } else if (resultApi.resCode == "000202" || resultApi.resMsg.Contains("商户已注册")) {
                    return ApiResultToJson.Json(new merchant_register_result { merchant_no = resultApi.data });
                } else {
                    return ApiResultToJson.Json<merchant_register_result>(resultApi.resMsg);
                }
            }
            return ApiResultToJson.Json<merchant_register_result>("信息登记异常");
        }

        /// <summary>
        /// 编辑商户进件
        /// </summary>
        /// <returns>The modify.</returns>
        /// <param name="bind_id">Bind identifier.</param>
        /// <param name="settle_type">Settle type.</param>
        /// <param name="channel">Channel.</param>
        public async Task<merchant_register_result> MerchantModify(long bind_id, string settle_type, PayChannel channel) {
            var binder = _iMerchantService.Get(bind_id);
            var binder_registers = _iMerchantService.GetRegisters(binder.id);
            var register = binder_registers.FirstOrDefault(c => c.pay_channel == channel);
            var merchant = _iMerchantService.Get(binder.oem_id.Value);
            var model = new merchant_edit_m2();
            model.merCode = register.merchant_no;
            model.Service = _xsft3Sign.Services[channel];
            SetMerchantInfo(model, binder);
            string url = SetUrlByChannel(channel, merchant_reg_url);
            var resultApi = await _xsft3Sign.PayGateway<merchant_resp>(model, url);
            if (resultApi != null && resultApi.resCode == "0000") { }

            var model2 = new merchant_edit_m4();
            model2.merCode = register.merchant_no;
            model2.Service = _xsft3Sign.Services[channel];
            SetPayType(model2, binder, channel);
            var resultApi2 = await _xsft3Sign.PayGateway<merchant_resp>(model2, url);
            if (resultApi2 != null && resultApi2.resCode == "0000") {
                var dto = binder.setting.auth_info.ToDtoObject<merchant_register_model>();
                dto.pay_channel = channel;
                dto.reg_merchant_no = register.merchant_no;
                dto.bind_no = binder.merchant_no;
                dto.merchant_no = merchant.merchant_no;
                _iMerchantService.MerchantChannelRegister(dto);
                return ApiResultToJson.Json(new merchant_register_result { merchant_no = resultApi2.data });
            }
            return ApiResultToJson.Json<merchant_register_result>("信息登记异常");
        }

        /// <summary>
        /// 通过商户实名新增商户信息
        /// </summary>
        /// <param name="model"></param>
        /// <param name="user"></param>
        private void SetMerchantInfo(merchant_req model, merchant_dto user) {
            var authinfo = user.setting.auth_info;
            model.accountNo = authinfo.account_no;
            model.bankName = authinfo.bank_name;
            model.accountName = authinfo.account_name;
            model.certId = authinfo.id_card;
            model.bankmobile = authinfo.mobile;
            model.userPhone = authinfo.mobile;
            var regions = _iRegionService.GetRegionIds(authinfo.region_id);
            var regionNames = _iRegionService.GetRegionNames(authinfo.region_id).Split(' ');
            model.merProvice = regions[0].ToString();
            model.merCity = regions[1].ToString();
            model.address = regionNames.Length > 1 ? regionNames[1] : regionNames[0];
            model.bankCode = SetMerchantBankCode(user.setting.auth_info.bank_code);
        }

        private void SetMerchantInfo(merchant_req model, merchant_register_model authinfo) {
            model.accountNo = authinfo.account_no;
            model.bankName = authinfo.bank_name;
            model.bankCode = SetMerchantBankCode(authinfo.bank_code);
            model.accountName = authinfo.account_name;
            model.certId = authinfo.id_card;
            model.bankmobile = authinfo.mobile;
            model.userPhone = authinfo.mobile;
            var regions = _iRegionService.GetRegionIds(authinfo.region_id);
            var regionNames = _iRegionService.GetRegionNames(authinfo.region_id).Split(' ');
            model.merProvice = regions[0].ToString();
            model.merCity = regions[1].ToString();
            model.address = regionNames.Length > 1 ? regionNames[1] : regionNames[0];
        }

        private void SetMerchantInfo(merchant_edit_m2 model, merchant_dto user) {
            var authinfo = user.setting.auth_info;
            model.accountNo = authinfo.account_no;
            model.bankName = authinfo.bank_name;
            model.accountName = authinfo.account_name;
            model.certId = authinfo.id_card;
            model.bankmobile = authinfo.mobile;
            model.merProvice = authinfo.province;
            model.merCity = authinfo.city;
            model.bankCode = SetMerchantBankCode(user.setting.auth_info.bank_code);
        }

        private void SetMerchantInfo(merchant_edit_m2 model, merchant_register_model authinfo) {
            model.accountNo = authinfo.account_no;
            model.bankName = authinfo.bank_name;
            model.accountName = authinfo.account_name;
            model.certId = authinfo.id_card;
            model.bankmobile = authinfo.mobile;
            var regions = _iRegionService.GetRegionIds(authinfo.region_id);
            var regionNames = _iRegionService.GetRegionNames(authinfo.region_id).Split(' ');
            model.merProvice = regions[0].ToString();
            model.merCity = regions[1].ToString();
            string address = regionNames[0] + (regionNames.Length > 1 ? regionNames[1] : regionNames[0]);
            model.address = address;
            model.bankCode = SetMerchantBankCode(authinfo.bank_code);
        }

        private string SetMerchantBankCode(string bank_code) {
            var banks = new Dictionary<string, string>();
            banks.Add("ABC", "103100000018");//103100000026
            banks.Add("BCM", "301290000007");
            banks.Add("BOC", "104100000045");//104100000004
            banks.Add("CCB", "105100000017");
            banks.Add("CEB", "303100000006");
            banks.Add("CGB", "306331003281");
            banks.Add("CIB", "309391000011");
            banks.Add("CITIC", "302100011000");
            banks.Add("CMB", "308584000013");
            banks.Add("CMBC", "305100000013");
            banks.Add("HXB", "304100040000");
            banks.Add("ICBC", "102100099996");
            banks.Add("PSBC", "403100000004");
            banks.Add("SPDB", "310290000013");
            banks.Add("PAB", "307584007998");
            banks.Add("BJB", "313100000013");
            banks.Add("SHB", "325290000012");
            return banks[bank_code];
        }

        private void SetPayType(merchant_req model, merchant_dto binder, PayChannel channel) {
            var binder_payments = _iMerchantService.GetPayments(binder.id);
            var payment = binder_payments.FirstOrDefault(c => c.payment.channel == channel);
            var settle = payment.settles.First(c => c.settle_type == "T0" && c.code == "UNIONPAY");
            model.Rate = model.scoreRate = settle.fee.ToString();
            model.Fee = model.scoreFee = ((int)(settle.settle * 100)).ToString();
        }

        private void SetPayType(merchant_req model, merchant_register_model user) {
            model.Rate = model.scoreRate = user.fee.ToString();
            model.Fee = model.scoreFee = user.settle;
        }

        private void SetPayType(merchant_edit_m4 model, merchant_dto binder, PayChannel channel) {
            var binder_payments = _iMerchantService.GetPayments(binder.id);
            var payment = binder_payments.FirstOrDefault(c => c.payment.channel == channel);
            var settle = payment.settles.First(c => c.settle_type == "T0" && c.code == "UNIONPAY");
            model.Rate = model.scoreRate = settle.fee.ToString();
            model.Fee = model.scoreFee = ((int)(settle.settle * 100)).ToString();
        }

        private void SetPayType(merchant_edit_m4 model, merchant_register_model user) {
            model.Rate = model.scoreRate = user.fee.ToString();
            model.Fee = model.scoreFee = user.settle;
        }
        #endregion

        #region 对账
        public Task<int> ItpToFile(DateTime create_date) {
            throw new NotImplementedException();
        }
        public int DealItp(long id) {
            throw new NotImplementedException();
        }
        #endregion

        #region 四要素
        /// <summary>
        /// 四要素
        /// </summary>
        /// <returns>The verify.</returns>
        /// <param name="dto">Model.</param>
        public Task<certify_verify_result> CertifyVerify(certify_verify dto) {
            throw new NotImplementedException();
        }

        public Task<mall_result> MallPay(mall_model obj) {
            throw new NotImplementedException();
        }
        #endregion

        private string SetUrlByChannel(PayChannel channel, string url) {
            string result = string.Empty;
            if (channel == PayChannel.UNIPAY) {
                result = string.Format(url, "v2pay");
            }
            if (channel == PayChannel.BaiHuoPay || channel == PayChannel.shanglvPay ||
                channel == PayChannel.SCORE || channel == PayChannel.ScenePay ||
                channel == PayChannel.TopPay || channel == PayChannel.Slscore) {
                result = string.Format(url, "kjv2pay");
            }
            return result;
        }

        public Task<transfer_result> TokenTransfer(long id) {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TokenTransferQuery(transfer_query model) {
            throw new NotImplementedException();
        }
    }
}